// xlocale internal header (from <locale>)
#ifndef _XLOCALE_
#define _XLOCALE_
#include <climits>
#include <cstring>
#include <stdexcept>
#include <typeinfo>
#include <xlocinfo>

 #define _BEGIN_LOCINFO(x)	_BEGIN_LOCK(_LOCK_LOCALE) _Locinfo x;
 #define _END_LOCINFO()		_END_LOCK()

_C_STD_BEGIN
_EXTERN_C
_MRTIMP2 void *_CDECL _Getgloballocale();
_MRTIMP2 void _CDECL _Setgloballocale(void *);
_END_EXTERN_C
_C_STD_END

_STD_BEGIN
	// CLASS _Facet_base
class _CRTIMP2P _Facet_base
	{	// code for reference counting a facet
public:
	virtual _CTHIS ~_Facet_base() _NOEXCEPT
		{	// ensure that derived classes can be destroyed properly
		}

	virtual void _CTHIS _Incref() = 0;	// increment use count
	virtual _Facet_base *_CTHIS _Decref() = 0;	// decrement use count
	};

		// TEMPLATE CLASS _Locbase
template<class _Dummy>
	class _CRTIMP2 _Locbase
	{	// define templatized category constants, instantiate on demand
public:
	_PGLOBAL static const int collate = _M_COLLATE;
	_PGLOBAL static const int ctype = _M_CTYPE;
	_PGLOBAL static const int monetary = _M_MONETARY;
	_PGLOBAL static const int numeric = _M_NUMERIC;
	_PGLOBAL static const int time = _M_TIME;
	_PGLOBAL static const int messages = _M_MESSAGES;
	_PGLOBAL static const int all = _M_ALL;
	_PGLOBAL static const int none = 0;
	};

template<class _Dummy>
	const int _Locbase<_Dummy>::collate;
template<class _Dummy>
	const int _Locbase<_Dummy>::ctype;
template<class _Dummy>
	const int _Locbase<_Dummy>::monetary;
template<class _Dummy>
	const int _Locbase<_Dummy>::numeric;
template<class _Dummy>
	const int _Locbase<_Dummy>::time;
template<class _Dummy>
	const int _Locbase<_Dummy>::messages;
template<class _Dummy>
	const int _Locbase<_Dummy>::all;
template<class _Dummy>
	const int _Locbase<_Dummy>::none;

		// CLASS locale
class _CRTIMP2 locale;
template<class _Facet>
	const _Facet& _CRTDECL use_facet(const locale&);
template<class _Elem>
	class collate;

class  _CRTIMP2 locale
	: public _Locbase<int>
	{	// nonmutable collection of facets that describe a locale
public:
	typedef int category;

			// CLASS id
	class _CRTIMP2P id
		{	// identifier stamp, unique for each distinct kind of facet
	public:
		_CTHIS id(size_t _Val = 0)
			: _Id(_Val)
			{	// construct with specified stamp value
			}

		_CTHIS operator size_t()
			{	// get stamp, with lazy allocation
			if (_Id == 0)
				{	// still zero, allocate stamp
				_BEGIN_LOCK(_LOCK_LOCALE)
					if (_Id == 0)
						_Id = ++_Id_cnt;
				_END_LOCK()
				}
			return (_Id);
			}

	private:
		size_t _Id;	// the identifier stamp

		__PURE_APPDOMAIN_GLOBAL static int _Id_cnt;

 #if _HAS_FUNCTION_DELETE
	public:
		_CTHIS id(const id&) = delete;
		id& _CTHIS operator=(const id&) = delete;

 #else /* _HAS_FUNCTION_DELETE */
		_CTHIS id(const id&);	// not defined
		id& _CTHIS operator=(const id&);	// not defined
 #endif /* _HAS_FUNCTION_DELETE */
		};

	class _Locimp;

			// CLASS facet
	class _CRTIMP2P facet
		: public _Facet_base
		{	// base class for all locale facets, performs reference counting
	public:
		static size_t _CCDECL _Getcat(const facet ** = 0,
			const locale * = 0)
			{	// get category value, or -1 if no corresponding C category
			return ((size_t)(-1));
			}

		void _CTHIS _Register();	// queue lazy facet destruction

		virtual void _CTHIS _Incref()
			{	// increment use count
			_MT_INCR(_Mtx, _Myrefs);
			}

		virtual _Facet_base *_CTHIS _Decref()
			{	// decrement use count
			if (_MT_DECR(_Mtx, _Myrefs) == 0)
				return (this);
			else
				return (0);
			}

 #if _USE_ATOMIC_OPS
	private:
		_Atomic_counter_t _Myrefs;	// the reference count

	protected:
		explicit _CTHIS facet(size_t _Initrefs = 0)
			{	// construct with initial reference count
			_Init_atomic_counter(_Myrefs, (_Atomic_integral_t)_Initrefs);
			}

	public:
		virtual _CTHIS ~facet() _NOEXCEPT
			{	// ensure that derived classes can be destroyed properly
			}

		bool _Shared() const
			{	// test if more than one owner
			return (1 < _Get_atomic_count(_Myrefs));
			}

 #else /* _USE_ATOMIC_OPS */
	private:
		long _Myrefs;

  #if _MULTI_THREAD
		_Rmtx _Mtx;	// the mutex

	protected:
		explicit _CTHIS facet(size_t _Initrefs = 0)
			: _Myrefs((long)_Initrefs)
			{	// construct
			_Mtxinit(&_Mtx);
			}

	public:
		virtual _CTHIS ~facet() _NOEXCEPT
			{	// destroy mutex
			_Mtxdst(&_Mtx);
			}

  #else /* _MULTI_THREAD */
	protected:
		explicit _CTHIS facet(size_t _Initrefs = 0)
			: _Myrefs((long)_Initrefs)
			{	// construct
			}

	public:
		virtual _CTHIS ~facet() _NOEXCEPT
			{	// ensure that derived classes can be destroyed properly
			}
  #endif /* _MULTI_THREAD */

		bool _Shared() const
			{	// test if more than one owner
			return (1 < _Myrefs);
			}
 #endif /* _USE_ATOMIC_OPS */

 #if _HAS_FUNCTION_DELETE
	public:
		_CTHIS facet(const facet&) = delete;
		facet& _CTHIS operator=(const facet&) = delete;

 #else /* _HAS_FUNCTION_DELETE */
	private:
		_CTHIS facet(const facet&);	// not defined
 #endif /* _HAS_FUNCTION_DELETE */
		};

			// CLASS _Locimp

	class _CRTIMP2P _Locimp
		: public facet
		{	// reference-counted actual implementation of a locale
	protected:
		_CTHIS ~_Locimp() _NOEXCEPT;	// destroy the object

	private:
		friend class locale;

		static _Locimp *_CCDECL _New_Locimp(bool _Transparent = false)
			{	// allocate new _Locimp
			return (new _Locimp(_Transparent));
			}

		static _Locimp *_CCDECL _New_Locimp(const _Locimp& _Right)
			{	// allocate new _Locimp by copying
			return (new _Locimp(_Right));
			}

		_CTHIS _Locimp(bool _Transparent = false);	// construct from current locale

		_CTHIS _Locimp(const _Locimp&);	// copy a _Locimp

		void _CTHIS _Addfac(facet *, size_t);	// add a facet

		static _Locimp *_CCDECL _Makeloc(const _Locinfo&,
			category, _Locimp *, const locale *);	// make essential facets

		static void _CCDECL _Makewloc(const _Locinfo&,
			category, _Locimp *, const locale *);	// make wchar_t facets

		static void _CCDECL _Makexloc(const _Locinfo&,
			category, _Locimp *, const locale *);	// make remaining facets

		facet **_Facetvec;	// pointer to vector of facets
		size_t _Facetcount;	// size of vector of facets
		category _Catmask;	// mask describing implemented categories
		bool _Xparent;	// true if locale is transparent

		_Yarn<char> _Name;	// locale name, or "*" if not known

		static _Locimp *_Clocptr;	// pointer to "C" locale object
		};

	template<class _Elem,
		class _Traits,
		class _Alloc>
		bool operator()(const basic_string<_Elem, _Traits, _Alloc>&,
			const basic_string<_Elem, _Traits, _Alloc>&)
				const;	// compare strings

	template<class _Facet>
		locale combine(const locale& _Loc) const
		{	// combine locale with facet from _Loc
		_Facet *_Facptr;

		_TRY_BEGIN
			_Facptr = (_Facet *)&use_facet<_Facet>(_Loc);
		_CATCH_ALL
			_Xruntime_error("locale::combine facet missing");
		_CATCH_END

		_Locimp *_Newimp = _Locimp::_New_Locimp(*_Ptr);
		_Newimp->_Addfac(_Facptr, _Facet::id);
		_Newimp->_Catmask = none;
		_Newimp->_Name = "*";
		return (locale(_Newimp));
		}

	template<class _Facet>
		locale(const locale& _Loc, const _Facet *_Facptr)
			: _Ptr(_Locimp::_New_Locimp(*_Loc._Ptr))
		{	// construct from _Loc, replacing facet with *_Facptr
		if (_Facptr != 0)
			{	// replace facet
			_Ptr->_Addfac((_Facet *)_Facptr, _Facet::id);
			_Ptr->_Catmask = none;
			_Ptr->_Name = "*";
			}
		}

	locale(_Uninitialized)
		{	// defer construction
		}

 #if _NO_LOCALES
	locale(const locale& _Right) _THROW0()
		: _Ptr(0)
		{	// construct by copying
		}

	locale() _THROW0()
		: _Ptr(0)
		{	// construct from current locale
		}

	~locale() _NOEXCEPT
		{	// destroy the object
		}

	locale& operator=(const locale& _Right) _THROW0()
		{	// assign a locale
		return (*this);
		}

 #else /* _NO_LOCALES */
	locale(const locale& _Right) _THROW0()
		: _Ptr(_Right._Ptr)
		{	// construct by copying
		_Ptr->_Incref();
		}

	locale() _THROW0()
		: _Ptr(_Init(true))
		{	// construct from current locale
		}

 #if !defined(MRTDLL) || !defined(_CRTBLD)
	locale(const locale& _Loc, const locale& _Other,
		category _Cat)
		: _Ptr(_Locimp::_New_Locimp(*_Loc._Ptr))
		{	// construct a locale by copying named facets
		if (_Cat != none)
			{	// worth adding, do it
			_TRY_BEGIN
				_BEGIN_LOCINFO(_Lobj)
					_Locimp::_Makeloc(_Lobj, _Cat, _Ptr, &_Other);
					_Lobj._Addcats(_Loc._Ptr->_Catmask,
						_Loc.name().c_str());
					_Lobj._Addcats(_Other._Ptr->_Catmask,
						_Other.name().c_str());
					_Ptr->_Catmask = _Loc._Ptr->_Catmask
						| _Other._Ptr->_Catmask;
					_Ptr->_Name = _Lobj._Getname();
				_END_LOCINFO()
			_CATCH_ALL
			delete _Ptr->_Decref();
			_RERAISE;
			_CATCH_END
			}
		}

private:
	void _Construct(const string &_Str,
		category _Cat)
		{	// construct a locale with named facets
		bool _Bad = false;
		_Init();
		if (_Cat != none)
			{	// worth adding, do it
			_TRY_BEGIN
				_BEGIN_LOCINFO(_Lobj(_Cat, _Str.c_str()))
					if (_Badname(_Lobj))
						_Bad = true;
					else
						{	// name okay, build the locale
						_Locimp::_Makeloc(_Lobj, _Cat, _Ptr, 0);
						_Ptr->_Catmask = _Cat;
						_Ptr->_Name = _Str.c_str();
						}
				_END_LOCINFO()
			_CATCH_ALL
			delete _Ptr->_Decref();
			_RERAISE;
			_CATCH_END
			}

		if (_Bad)
			{	// Don't throw within _BEGIN_LOCINFO if we can avoid it
			delete _Ptr->_Decref();
			_Xruntime_error("bad locale name");
			}
		}

public:
	explicit locale(const char *_Locname,
		category _Cat = all)
		: _Ptr(_Locimp::_New_Locimp())
		{	// construct a locale with named facets
		// _Locname might have been returned from setlocale().
		// Therefore, _Construct() takes const string&.
		if (_Locname == 0)
			_Xruntime_error("bad locale name");
		_Construct(_Locname, _Cat);
		}

	locale(const locale& _Loc, const char *_Locname,
		category _Cat)
		: _Ptr(_Locimp::_New_Locimp(*_Loc._Ptr))
		{	// construct a locale by copying, replacing named facets
		// _Locname might have been returned from setlocale().
		// Therefore, _Construct() takes const string&.
		if (_Locname == 0)
			_Xruntime_error("bad locale name");
		_Construct(_Locname, _Cat);
		}

 #if _HAS_CPP0X
	explicit locale(const string& _Str,
		category _Cat = all)
		: _Ptr(_Locimp::_New_Locimp())
		{	// construct a locale with named facets
		_Construct(_Str, _Cat);
		}

	locale(const locale& _Loc, const string& _Str,
		category _Cat)
		: _Ptr(_Locimp::_New_Locimp(*_Loc._Ptr))
		{	// construct a locale by copying, replacing named facets
		_Construct(_Str, _Cat);
		}
 #endif /* _HAS_CPP0X */

 #endif /* !MRTDLL || !_CRTBLD */

	~locale() _NOEXCEPT
		{	// destroy the object
		if (_Ptr != 0)
			delete _Ptr->_Decref();
		}

	locale& operator=(const locale& _Right) _THROW0()
		{	// assign a locale
		if (_Ptr != _Right._Ptr)
			{	// different implementation, point at new one
			delete _Ptr->_Decref();
			_Ptr = _Right._Ptr;
			_Ptr->_Incref();
			}
		return (*this);
		}
 #endif /* _NO_LOCALES */

	string name() const
		{	// return locale name
		return (_Ptr == 0 ? string() : _Ptr->_Name.c_str());
		}

	const char *c_str() const
		{	// return locale name as NTBS
		return (_Ptr == 0 ? "" : _Ptr->_Name.c_str());
		}

	const facet *_Getfacet(size_t _Id) const
		{	// look up a facet in locale object
		const facet *_Facptr = _Id < _Ptr->_Facetcount
			? _Ptr->_Facetvec[_Id] : 0;	// null if id off end
		if (_Facptr != 0 || !_Ptr->_Xparent)
			return (_Facptr);	// found facet or not transparent
		else
			{	// look in current locale
			locale::_Locimp *_Ptr0 = _Getgloballocale();
			return (_Id < _Ptr0->_Facetcount
				? _Ptr0->_Facetvec[_Id]	// get from current locale
				: 0);	// no entry in current locale
			}
		}

	bool operator==(const locale& _Loc) const
		{	// compare locales for equality
		return (_Ptr == _Loc._Ptr
			|| (name().compare("*") != 0
				&& name().compare(_Loc.name()) == 0));
		}

	bool operator!=(const locale& _Right) const
		{	// test for locale inequality
		return (!(*this == _Right));
		}

	static _MRTIMP2 const locale& _CDECL classic();	// classic "C" locale

	static _MRTIMP2 locale _CDECL global(const locale&);	// current locale

	static _MRTIMP2 locale _CDECL empty();	// empty (transparent) locale

private:
	locale(_Locimp *_Ptrimp)
		: _Ptr(_Ptrimp)
		{	// construct from _Locimp pointer
		}

	static _MRTIMP2 _Locimp *_CDECL _Init(
		bool _Do_incref = false);	// initialize locale
	static _MRTIMP2 _Locimp *_CDECL _Getgloballocale();
	static _MRTIMP2 void _CDECL _Setgloballocale(void *);

	bool _Badname(const _Locinfo& _Lobj)
		{	// test if name is "*"
		return (_CSTD strcmp(_Lobj._Getname(), "*") == 0);
		}

	_Locimp *_Ptr;	// pointer to locale implementation object
	};

		// SUPPORT TEMPLATES

 #if _NO_LOCALES
inline _Locinfo& _Get_locinfo()
	{	// get reference to common locale info
	static _Locinfo _Lobj;
	return (_Lobj);
	}

template<class _Facet>
	class _Wrap_facet
		: public _Facet
	{	// makes a facet destructible and shareable
public:
	_Wrap_facet()
		: _Facet(_Get_locinfo())
		{	// construct from locale object
		}
	};
 #endif /* _NO_LOCALES */

template<class _Facet>
	struct _Facetptr
	{	// store pointer to lazy facet for use_facet
	__PURE_APPDOMAIN_GLOBAL static const locale::facet *_Psave;
	};

template<class _Facet>
	__PURE_APPDOMAIN_GLOBAL const locale::facet *_Facetptr<_Facet>::
		_Psave = 0;

 #define _ADDFAC(loc, pfac)	locale(loc, pfac)	/* add facet to locale */

 #define _USE(loc, fac)	\
	use_facet< fac >(loc)	/* get facet reference from locale */

template<class _Facet> inline
	const _Facet& _CDECL use_facet(const locale& _Loc)

	{	// get facet reference from locale
 #if _NO_LOCALES
	static _Wrap_facet<_Facet> _Wfac;
	return (*(_Facet *)&_Wfac);

 #else /* _NO_LOCALES */
	_BEGIN_LOCK(_LOCK_LOCALE)	// the thread lock, make get atomic
		const locale::facet *_Psave =
			_Facetptr<_Facet>::_Psave;	// static pointer to lazy facet

		size_t _Id = _Facet::id;
		const locale::facet *_Pf = _Loc._Getfacet(_Id);

		if (_Pf != 0)
			;	// got facet from locale
		else if (_Psave != 0)
			_Pf = _Psave;	// lazy facet already allocated
		else if (_Facet::_Getcat(&_Psave, &_Loc) == (size_t)(-1))

 #if _HAS_EXCEPTIONS
			_THROW1(_XSTD bad_cast());	// lazy disallowed

 #else /* _HAS_EXCEPTIONS */
			abort();	// lazy disallowed
 #endif /* _HAS_EXCEPTIONS */

		else
			{	// queue up lazy facet for destruction
			_Pf = _Psave;
			_Facetptr<_Facet>::_Psave = _Psave;

			locale::facet *_Pfmod = (_Facet *)_Psave;
			_Pfmod->_Incref();
			_Pfmod->_Register();
			}

		return ((const _Facet&)(*_Pf));	// should be dynamic_cast
	_END_LOCK()
 #endif /* _NO_LOCALES */
	}	// end of use_facet body

		// TEMPLATE FUNCTION _Getloctxt
template<class _Elem,
	class _InIt> inline
	int _CRTDECL _Getloctxt(_InIt& _First, _InIt& _Last, size_t _Numfields,
		const _Elem *_Ptr)
	{	// find field at _Ptr that matches longest in [_First, _Last)
	for (size_t _Off = 0; _Ptr[_Off] != (_Elem)0; ++_Off)
		if (_Ptr[_Off] == _Ptr[0])
			++_Numfields;	// add fields with leading mark to initial count
	string _Str(_Numfields, '\0');	// one column counter for each field

	int _Ans = -2;	// no candidates so far
	for (size_t _Column = 1; ; ++_Column, ++_First, _Ans = -1)
		{	// test each element against all viable fields
		bool _Prefix = false;	// seen at least one valid prefix
		size_t _Off = 0;	// offset into fields
		size_t _Field = 0;	// current field number

		for (; _Field < _Numfields; ++_Field)
			{	// test element at _Column in field _Field
			for (; _Ptr[_Off] != (_Elem)0 && _Ptr[_Off] != _Ptr[0]; ++_Off)
				;	// find beginning of field

			if (_Str[_Field] != '\0')
				_Off += _Str[_Field];	// skip tested columns in field
			else if (_Ptr[_Off += _Column] == _Ptr[0]
				|| _Ptr[_Off] == (_Elem)0)
				{	// matched all of field, save as possible answer
				_Str[_Field] = (char)(_Column < 127
					? _Column : 127);	// save skip count if small enough
				_Ans = (int)_Field;	// save answer
				}
			else if (_First == _Last || _Ptr[_Off] != *_First)
				_Str[_Field] = (char)(_Column < 127
					? _Column : 127);	// no match, just save skip count
			else
				_Prefix = true;	// still a valid prefix
			}

		if (!_Prefix || _First == _Last)
			break;	// no pending prefixes or no input, give up
		}
	return (_Ans);	// return field number or negative value on failure
	}

		// TEMPLATE FUNCTION _Maklocbyte
#define _MAKLOCBYTE(Elem, chr, cvt) \
	_Maklocbyte((_Elem)chr, cvt)	/* convert Elem to char */

template<class _Elem> inline
	char _CRTDECL _Maklocbyte(_Elem _Char,
		const _Locinfo::_Cvtvec&)
	{	// convert _Elem to char using _Cvtvec
	return ((char)(unsigned char)_Char);
	}

template<> inline
	char _CRTDECL _Maklocbyte(wchar_t _Char,
		const _Locinfo::_Cvtvec& _Cvt)
	{	// convert wchar_t to char using _Cvtvec
	char _Byte = '\0';
	_Mbstinit(_Mbst1);
	_Wcrtomb(&_Byte, _Char, &_Mbst1, &_Cvt);
	return (_Byte);
	}

		// TEMPLATE FUNCTION _Maklocchr
#define _MAKLOCCHR(Elem, chr, cvt) \
	_Maklocchr(chr, (Elem *)0, cvt)	/* convert char to Elem */

template<class _Elem> inline
	_Elem _CRTDECL _Maklocchr(char _Byte, _Elem *,
		const _Locinfo::_Cvtvec&)
	{	// convert char to _Elem using _Cvtvec
	return ((_Elem)(unsigned char)_Byte);
	}

template<> inline
	wchar_t _CRTDECL _Maklocchr(char _Byte, wchar_t *,
		const _Locinfo::_Cvtvec& _Cvt)
	{	// convert char to wchar_t using _Cvtvec
	wchar_t _Wc = L'\0';
	_Mbstinit(_Mbst1);
	_Mbrtowc(&_Wc, &_Byte, 1, &_Mbst1, &_Cvt);
	return (_Wc);
	}

		// TEMPLATE FUNCTION _Maklocstr
#define _MAKLOCSTR(Elem, str, cvt)	\
	_Maklocstr(str, (Elem *)0, cvt)	/* convert C string to Elem sequence */

template<class _Elem> inline
	_Elem *_CRTDECL _Maklocstr(const char *_Ptr, _Elem *,
		const _Locinfo::_Cvtvec&)
	{	// convert C string to _Elem sequence using _Cvtvec
	size_t _Count = _CSTD strlen(_Ptr) + 1;
	_Elem *_Ptrdest = (_Elem *)_CSTD malloc(_Count);
	if (!_Ptrdest)
		_Xbad_alloc();

	for (_Elem *_Ptrnext = _Ptrdest; 0 < _Count; --_Count, ++_Ptrnext, ++_Ptr)
		*_Ptrnext = (_Elem)(unsigned char)*_Ptr;
	return (_Ptrdest);
	}

template<> inline
	wchar_t *_CRTDECL _Maklocstr(const char *_Ptr, wchar_t *,
		const _Locinfo::_Cvtvec& _Cvt)
	{	// convert C string to wchar_t sequence using _Cvtvec
	size_t _Count, _Count1;
	size_t _Wchars;
	const char *_Ptr1;
	int _Bytes;
	wchar_t _Wc;
	_Mbstinit(_Mbst1);

	_Count1 = _CSTD strlen(_Ptr) + 1;
	for (_Count = _Count1, _Wchars = 0, _Ptr1 = _Ptr; 0 < _Count;
		_Count -= _Bytes, _Ptr1 += _Bytes, ++_Wchars)
		if ((_Bytes = _Mbrtowc(&_Wc, _Ptr1, _Count, &_Mbst1, &_Cvt)) <= 0)
			break;
	++_Wchars;	// count terminating nul

	wchar_t *_Ptrdest = (wchar_t *)_CSTD malloc(_Wchars * sizeof (wchar_t));
	if (!_Ptrdest)
		_Xbad_alloc();
	wchar_t *_Ptrnext = _Ptrdest;
	_Mbstinit(_Mbst2);

	for (; 0 < _Wchars;
		_Count -= _Bytes, _Ptr += _Bytes, --_Wchars, ++_Ptrnext)
		if ((_Bytes = _Mbrtowc(_Ptrnext, _Ptr, _Count1, &_Mbst2, &_Cvt)) <= 0)
			break;
	*_Ptrnext = L'\0';
	return (_Ptrdest);
	}

		// STRUCT codecvt_base

class _CRTIMP2P codecvt_base
	: public locale::facet
	{	// base class for codecvt
public:
	enum
		{	// constants for different parse states
		ok, partial, error, noconv};
	typedef int result;

	_CTHIS codecvt_base(size_t _Refs = 0)
		: locale::facet(_Refs)
		{	// default constructor
		}

	bool _CTHIS always_noconv() const _THROW0()
		{	// return true if conversions never change input (from codecvt)
		return (do_always_noconv());
		}

	int _CTHIS max_length() const _THROW0()
		{	// return maximum length required for a conversion (from codecvt)
		return (do_max_length());
		}

	int _CTHIS encoding() const _THROW0()
		{	// return length of code sequence (from codecvt)
		return (do_encoding());
		}

	_CTHIS ~codecvt_base() _NOEXCEPT
		{	// destroy the object
		}

protected:
	virtual bool _CTHIS do_always_noconv() const _THROW0()
		{	// return true if conversions never change input (from codecvt)
		return (false);
		}

	virtual int _CTHIS do_max_length() const _THROW0()
		{	// return maximum length required for a conversion (from codecvt)
		return (1);
		}

	virtual int _CTHIS do_encoding() const _THROW0()
		{	// return length of code sequence (from codecvt)
		return (1);	// -1 ==> state dependent, 0 ==> varying length
		}
	};

		// TEMPLATE CLASS codecvt
template<class _Elem,
	class _Byte,
	class _Statype>
	class codecvt
		: public codecvt_base
	{	// facet for converting between _Elem and char (_Byte) sequences
public:
	typedef _Elem intern_type;
	typedef _Byte extern_type;
	typedef _Statype state_type;

	result _CTHIS in(_Statype& _State,
		const _Byte *_First1, const _Byte *_Last1, const _Byte *& _Mid1,
		_Elem *_First2, _Elem *_Last2, _Elem *& _Mid2) const
		{	// convert bytes [_First1, _Last1) to [_First2, _Last)
		return (do_in(_State,
			_First1, _Last1, _Mid1, _First2, _Last2, _Mid2));
		}

	result _CTHIS out(_Statype& _State,
		const _Elem *_First1, const _Elem *_Last1, const _Elem *& _Mid1,
		_Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
		{	// convert [_First1, _Last1) to bytes [_First2, _Last2)
		return (do_out(_State,
			_First1, _Last1, _Mid1, _First2, _Last2, _Mid2));
		}

	result _CTHIS unshift(_Statype& _State,
		_Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
		{	// generate bytes to return to default shift state
		return (do_unshift(_State, _First2, _Last2, _Mid2));
		}

	int _CTHIS length(_Statype& _State, const _Byte *_First1,
		const _Byte *_Last1, size_t _Count) const
		{	// return min(_Count, converted length of bytes [_First1, _Last1))
		return (do_length(_State, _First1, _Last1, _Count));
		}

	__PURE_APPDOMAIN_GLOBAL static locale::id id;	// unique facet id

	explicit _CTHIS codecvt(size_t _Refs = 0)
		: codecvt_base(_Refs)
		{	// construct from current locale
		_Init(_Locinfo());
		}

	_CTHIS codecvt(const _Locinfo& _Lobj, size_t _Refs = 0)
		: codecvt_base(_Refs)
		{	// construct from specified locale
		_Init(_Lobj);
		}

	static size_t _CCDECL _Getcat(const locale::facet **_Ppf = 0,
		const locale *_Ploc = 0)
		{	// return locale category mask and construct standard facet
		if (_Ppf != 0 && *_Ppf == 0)
			*_Ppf = new codecvt<_Elem, _Byte, _Statype>(
				_Locinfo(_Ploc->c_str()));
		return (_X_CTYPE);
		}

protected:
	virtual _CTHIS ~codecvt() _NOEXCEPT
		{	// destroy the object
		}

	void _CTHIS _Init(const _Locinfo&)
		{	// initialize from _Locinfo object
		}

	virtual bool _CTHIS do_always_noconv() const _THROW0()
		{	// return true if conversions never change input (from codecvt)
		return (is_same<_Byte, _Elem>::value);
		}

	virtual result _CTHIS do_in(_Statype&,
		const _Byte *_First1, const _Byte *_Last1, const _Byte *& _Mid1,
		_Elem *_First2, _Elem *_Last2, _Elem *& _Mid2) const
		{	// convert bytes [_First1, _Last1) to [_First2, _Last)
		_Mid1 = _First1, _Mid2 = _First2;
		if (is_same<_Byte, _Elem>::value)
			return (noconv);	// convert nothing
		else
			{	// types differ, copy one for one
			for (; _Mid1 != _Last1 && _Mid2 != _Last2; ++_Mid1, ++_Mid2)
				*_Mid2 = (_Elem)*_Mid1;
			return (ok);
			}
		}

	virtual result _CTHIS do_out(_Statype&,
		const _Elem *_First1, const _Elem *_Last1, const _Elem *& _Mid1,
		_Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
		{	// convert [_First1, _Last1) to bytes [_First2, _Last)
		_Mid1 = _First1, _Mid2 = _First2;
		if (is_same<_Byte, _Elem>::value)
			return (noconv);	// convert nothing
		else
			{	// types differ, copy one for one
			for (; _Mid1 != _Last1 && _Mid2 != _Last2; ++_Mid1, ++_Mid2)
				*_Mid2 = (_Byte)*_Mid1;
			return (ok);
			}
		}

	virtual result _CTHIS do_unshift(_Statype&,
		_Byte *_First2, _Byte *, _Byte *&_Mid2) const
		{	// generate bytes to return to default shift state
		_Mid2 = _First2;
		return (ok);	// convert nothing
		}

	virtual int _CTHIS do_length(_Statype&, const _Byte *_First1,
		const _Byte *_Last1, size_t _Count) const
		{	// return min(_Count, converted length of bytes [_First1, _Last1))
		return ((int)(_Count < (size_t)(_Last1 - _First1)
			? _Count : _Last1 - _First1));	// assume 1-to-1 conversion
		}
	};

		// STATIC codecvt::id OBJECT
template<class _Elem,
	class _Byte,
	class _Statype>
	__PURE_APPDOMAIN_GLOBAL locale::id codecvt<_Elem, _Byte, _Statype>::id;

 #if _HAS_CHAR16_T_LANGUAGE_SUPPORT
		// ENUM _Codecvt_mode
enum _Codecvt_mode {
	_Consume_header = 4,
	_Generate_header = 2
	};

		// CLASS codecvt<char16_t, char, _Mbstatet>
template<>
	class _CRTIMP2P codecvt<char16_t, char, _Mbstatet>
	: public codecvt_base
	{	// facet for converting between char16_t and UTF-8 byte sequences
public:
	typedef codecvt<char16_t, char, _Mbstatet> _Mybase;
	typedef char16_t _Elem;
	typedef char _Byte;
	typedef _Mbstatet _Statype;
	typedef _Elem intern_type;
	typedef _Byte extern_type;
	typedef _Statype state_type;

	result _CTHIS in(_Statype& _State,
		const _Byte *_First1, const _Byte *_Last1, const _Byte *& _Mid1,
		_Elem *_First2, _Elem *_Last2, _Elem *& _Mid2) const
		{	// convert bytes [_First1, _Last1) to [_First2, _Last)
		return (do_in(_State,
			_First1, _Last1, _Mid1, _First2, _Last2, _Mid2));
		}

	result _CTHIS out(_Statype& _State,
		const _Elem *_First1, const _Elem *_Last1, const _Elem *& _Mid1,
		_Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
		{	// convert [_First1, _Last1) to bytes [_First2, _Last)
		return (do_out(_State,
			_First1, _Last1, _Mid1, _First2, _Last2, _Mid2));
		}

	result _CTHIS unshift(_Statype& _State,
		_Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
		{	// generate bytes to return to default shift state
		return (do_unshift(_State,
			_First2, _Last2, _Mid2));
		}

	int _CTHIS length(_Statype& _State, const _Byte *_First1,
		const _Byte *_Last1, size_t _Count) const
		{	// return min(_Count, converted length of bytes [_First1, _Last1))
		return (do_length(_State, _First1, _Last1, _Count));
		}

	__PURE_APPDOMAIN_GLOBAL static locale::id id;

	explicit _CTHIS codecvt(size_t _Refs = 0)
		: codecvt_base(_Refs), _Maxcode(0x10ffff), _Mode(_Consume_header)
		{	// construct from current locale
		_BEGIN_LOCINFO(_Lobj)
			_Init(_Lobj);
		_END_LOCINFO()
		}

	_CTHIS codecvt(const _Locinfo& _Lobj, size_t _Refs = 0)
		: codecvt_base(_Refs), _Maxcode(0x10ffff), _Mode(_Consume_header)
		{	// construct from specified locale
		_Init(_Lobj);
		}

	_CTHIS codecvt(const _Locinfo& _Lobj, unsigned long _Maxcode_arg,
		_Codecvt_mode _Mode_arg, size_t _Refs = 0)
		: codecvt_base(_Refs), _Maxcode(_Maxcode_arg), _Mode(_Mode_arg)
		{	// construct from specified locale and parameters
		_Init(_Lobj);
		}

	static size_t _CCDECL _Getcat(const locale::facet **_Ppf = 0,
		const locale *_Ploc = 0)
		{	// return locale category mask and construct standard facet
		if (_Ppf != 0 && *_Ppf == 0)
			*_Ppf = new codecvt<_Elem, _Byte, _Statype>(
				_Locinfo(_Ploc->c_str()));
		return (_X_CTYPE);
		}

protected:
	virtual _CTHIS ~codecvt() _NOEXCEPT
		{	// destroy the object
		}

	void _CTHIS _Init(const _Locinfo&)
		{	// initialize
		}

	virtual result _CTHIS do_in(_Statype& _State,
		const _Byte *_First1, const _Byte *_Last1, const _Byte *& _Mid1,
		_Elem *_First2, _Elem *_Last2, _Elem *& _Mid2) const
		{	// convert bytes [_First1, _Last1) to [_First2, _Last2)
		unsigned short *_Pstate = (unsigned short *)&_State;
		_Mid1 = _First1;
		_Mid2 = _First2;

		for (; _Mid1 != _Last1 && _Mid2 != _Last2; )
			{	// convert a multibyte sequence
			unsigned char _By = (unsigned char)*_Mid1;
			unsigned long _Ch;
			int _Nextra, _Nskip;

			if (*_Pstate <= 1)
				;	// no leftover word
			else if (_By < 0x80 || 0xc0 <= _By)
				return (_Mybase::error);	// not continuation byte
			else
				{	// deliver second half of two-word value
				++_Mid1;
				*_Mid2++ = (_Elem)(*_Pstate | (_By & 0x3f));
				*_Pstate = 1;
				continue;
				}

			if (_By < 0x80)
				_Ch = _By, _Nextra = 0;
			else if (_By < 0xc0)
				{	// 0x80-0xdf not first byte
				++_Mid1;
				return (_Mybase::error);
				}
			else if (_By < 0xe0)
				_Ch = _By & 0x1f, _Nextra = 1;
			else if (_By < 0xf0)
				_Ch = _By & 0x0f, _Nextra = 2;
			else if (_By < 0xf8)
				_Ch = _By & 0x07, _Nextra = 3;
			else
				_Ch = _By & 0x03, _Nextra = _By < 0xfc ? 4 : 5;

			_Nskip = _Nextra < 3 ? 0 : 1;	// leave a byte for 2nd word
			_First1 = _Mid1;	// roll back point

			if (_Nextra == 0)
				++_Mid1;
			else if (_Last1 - _Mid1 < _Nextra + 1 - _Nskip)
				break;	// not enough input
			else
				for (++_Mid1; _Nskip < _Nextra; --_Nextra, ++_Mid1)
					if ((_By = (unsigned char)*_Mid1) < 0x80 || 0xc0 <= _By)
						return (_Mybase::error);	// not continuation byte
					else
						_Ch = _Ch << 6 | (_By & 0x3f);
			if (0 < _Nskip)
				_Ch <<= 6;	// get last byte on next call

			if ((_Maxcode < 0x10ffff ? _Maxcode : 0x10ffff) < _Ch)
				return (_Mybase::error);	// value too large
			else if (0xffff < _Ch)
				{	// deliver first half of two-word value, save second word
				unsigned short _Ch0 =
					(unsigned short)(0xd800 | (_Ch >> 10) - 0x0040);

				*_Mid2++ = (_Elem)_Ch0;
				*_Pstate = (unsigned short)(0xdc00 | (_Ch & 0x03ff));
				continue;
				}

			if (_Nskip == 0)
				;
			else if (_Mid1 == _Last1)
				{	// not enough bytes, noncanonical value
				_Mid1 = _First1;
				break;
				}
			else if ((_By = (unsigned char)*_Mid1++) < 0x80 || 0xc0 <= _By)
				return (_Mybase::error);	// not continuation byte
			else
				_Ch |= _By & 0x3f;	// complete noncanonical value

			if (*_Pstate == 0)
				{	// first time, maybe look for and consume header
				*_Pstate = 1;

				if ((_Mode & _Consume_header) != 0 && _Ch == 0xfeff)
					{	// drop header and retry
					result _Ans = do_in(_State, _Mid1, _Last1, _Mid1,
						_First2, _Last2, _Mid2);

					if (_Ans == _Mybase::partial)
						{	// roll back header determination
						*_Pstate = 0;
						_Mid1 = _First1;
						}
					return (_Ans);
					}
				}

			*_Mid2++ = (_Elem)_Ch;
			}

		return (_First1 == _Mid1 ? _Mybase::partial : _Mybase::ok);
		}

	virtual result _CTHIS do_out(_Statype& _State,
		const _Elem *_First1, const _Elem *_Last1, const _Elem *& _Mid1,
		_Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
		{	// convert [_First1, _Last1) to bytes [_First2, _Last)
		unsigned short *_Pstate = (unsigned short *)&_State;
		_Mid1 = _First1;
		_Mid2 = _First2;

		for (; _Mid1 != _Last1 && _Mid2 != _Last2; )
			{	// convert and put a wide char
			unsigned long _Ch;
			unsigned short _Ch1 = (unsigned short)*_Mid1;
			bool _Save = false;

			if (1 < *_Pstate)
				{	// get saved MS 11 bits from *_Pstate
				if (_Ch1 < 0xdc00 || 0xe000 <= _Ch1)
					return (_Mybase::error);	// bad second word
				_Ch = (*_Pstate << 10) | (_Ch1 - 0xdc00);
				}
			else if (0xd800 <= _Ch1 && _Ch1 < 0xdc00)
				{	// get new first word
				_Ch = (_Ch1 - 0xd800 + 0x0040) << 10;
				_Save = true;	// put only first byte, rest with second word
				}
			else
				_Ch = _Ch1;	// not first word, just put it

			_Byte _By;
			int _Nextra;

			if (_Ch < 0x0080)
				_By = (_Byte)_Ch, _Nextra = 0;
			else if (_Ch < 0x0800)
				_By = (_Byte)(0xc0 | _Ch >> 6), _Nextra = 1;
			else if (_Ch < 0x10000)
				_By = (_Byte)(0xe0 | _Ch >> 12), _Nextra = 2;
			else
				_By = (_Byte)(0xf0 | _Ch >> 18), _Nextra = 3;

			int _Nput = _Nextra < 3 ? _Nextra + 1 : _Save ? 1 : 3;

			if (_Last2 - _Mid2 < _Nput)
				break;	// not enough room, even without header
			else if (*_Pstate != 0 || (_Mode & _Generate_header) == 0)
				;	// no header to put
			else if (_Last2 - _Mid2 < 3 + _Nput)
				break;	// not enough room for header + output
			else
				{	// prepend header
				*_Mid2++ = (_Byte)(unsigned char)0xef;
				*_Mid2++ = (_Byte)(unsigned char)0xbb;
				*_Mid2++ = (_Byte)(unsigned char)0xbf;
				}

			++_Mid1;
			if (_Save || _Nextra < 3)
				{	// put first byte of sequence, if not already put
				*_Mid2++ = _By;
				--_Nput;
				}
			for (; 0 < _Nput; --_Nput)
				*_Mid2++ = (_Byte)((_Ch >> 6 * --_Nextra & 0x3f) | 0x80);

			*_Pstate = (unsigned short)(_Save ? _Ch >> 10 : 1);
			}

		return (_First1 == _Mid1 ? _Mybase::partial : _Mybase::ok);
		}

	virtual result _CTHIS do_unshift(_Statype& _State,
		_Byte *_First2, _Byte *, _Byte *& _Mid2) const
		{	// generate bytes to return to default shift state
		unsigned short *_Pstate = (unsigned short *)&_State;
		_Mid2 = _First2;

		return (1 < *_Pstate
			? _Mybase::error : _Mybase::ok);	// fail if trailing first word
		}

	virtual int _CTHIS do_length(_Statype& _State, const _Byte *_First1,
		const _Byte *_Last1, size_t _Count) const
		{	// return min(_Count, converted length of bytes [_First1, _Last1))
		size_t _Wchars = 0;
		_Statype _Mystate = _State;

		for (; _Wchars < _Count && _First1 != _Last1; )
			{	// convert another wide character
			const _Byte *_Mid1;
			_Elem *_Mid2;
			_Elem _Ch;

			switch (do_in(_Mystate, _First1, _Last1, _Mid1,
				&_Ch, &_Ch + 1, _Mid2))
				{	// test result of single wide-char conversion
			case _Mybase::noconv:
				return ((int)(_Wchars + (_Last1 - _First1)));

			case _Mybase::ok:
				if (_Mid2 == &_Ch + 1)
					++_Wchars;	// replacement do_in might not convert one
				_First1 = _Mid1;
				break;

			default:
				return ((int)_Wchars);	// error or partial
				}
			}

		return ((int)_Wchars);
		}

	virtual bool _CTHIS do_always_noconv() const _THROW0()
		{	// return true if conversions never change input
		return (false);
		}

	virtual int _CTHIS do_max_length() const _THROW0()
		{	// return maximum length required for a conversion
		return ((_Mode & _Consume_header) != 0 ? 9	// header + max input
			: (_Mode & _Generate_header) != 0 ? 7	// header + max output
			: 6);	// 6-byte max input sequence, no 3-byte header
		}

	virtual int do_encoding() const _THROW0()
		{	// return length of code sequence (from codecvt)
		return (0);	// 0 => varying length
		}

private:
	unsigned long _Maxcode;	// default: 0x10ffff
	_Codecvt_mode _Mode;	// default: _Consume_header
	};

		// CLASS codecvt<char32_t, char, _Mbstatet>
template<>
	class _CRTIMP2P codecvt<char32_t, char, _Mbstatet>
	: public codecvt_base
	{	// facet for converting between char32_t and UTF-8 byte sequences
public:
	typedef codecvt<char32_t, char, _Mbstatet> _Mybase;
	typedef char32_t _Elem;
	typedef char _Byte;
	typedef _Mbstatet _Statype;
	typedef _Elem intern_type;
	typedef _Byte extern_type;
	typedef _Statype state_type;

	result _CTHIS in(_Statype& _State,
		const _Byte *_First1, const _Byte *_Last1, const _Byte *& _Mid1,
		_Elem *_First2, _Elem *_Last2, _Elem *& _Mid2) const
		{	// convert bytes [_First1, _Last1) to [_First2, _Last)
		return (do_in(_State,
			_First1, _Last1, _Mid1, _First2, _Last2, _Mid2));
		}

	result _CTHIS out(_Statype& _State,
		const _Elem *_First1, const _Elem *_Last1, const _Elem *& _Mid1,
		_Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
		{	// convert [_First1, _Last1) to bytes [_First2, _Last)
		return (do_out(_State,
			_First1, _Last1, _Mid1, _First2, _Last2, _Mid2));
		}

	result _CTHIS unshift(_Statype& _State,
		_Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
		{	// generate bytes to return to default shift state
		return (do_unshift(_State,
			_First2, _Last2, _Mid2));
		}

	int _CTHIS length(_Statype& _State, const _Byte *_First1,
		const _Byte *_Last1, size_t _Count) const
		{	// return min(_Count, converted length of bytes [_First1, _Last1))
		return (do_length(_State, _First1, _Last1, _Count));
		}

	__PURE_APPDOMAIN_GLOBAL static locale::id id;

	explicit _CTHIS codecvt(size_t _Refs = 0)
		: codecvt_base(_Refs), _Maxcode(0xffffffff), _Mode(_Consume_header)
		{	// construct from current locale
		_BEGIN_LOCINFO(_Lobj)
			_Init(_Lobj);
		_END_LOCINFO()
		}

	_CTHIS codecvt(const _Locinfo& _Lobj, size_t _Refs = 0)
		: codecvt_base(_Refs), _Maxcode(0xffffffff), _Mode(_Consume_header)
		{	// construct from specified locale
		_Init(_Lobj);
		}

	_CTHIS codecvt(const _Locinfo& _Lobj, unsigned long _Maxcode_arg,
		_Codecvt_mode _Mode_arg, size_t _Refs = 0)
		: codecvt_base(_Refs), _Maxcode(_Maxcode_arg), _Mode(_Mode_arg)
		{	// construct from specified locale and parameters
		_Init(_Lobj);
		}

	static size_t _CCDECL _Getcat(const locale::facet **_Ppf = 0,
		const locale *_Ploc = 0)
		{	// return locale category mask and construct standard facet
		if (_Ppf != 0 && *_Ppf == 0)
			*_Ppf = new codecvt<_Elem, _Byte, _Statype>(
				_Locinfo(_Ploc->c_str()));
		return (_X_CTYPE);
		}

protected:
	virtual _CTHIS ~codecvt() _NOEXCEPT
		{	// destroy the object
		}

	void _CTHIS _Init(const _Locinfo&)
		{	// initialize
		}

	virtual result _CTHIS do_in(_Statype& _State,
		const _Byte *_First1, const _Byte *_Last1, const _Byte *& _Mid1,
		_Elem *_First2, _Elem *_Last2, _Elem *& _Mid2) const
		{	// convert bytes [_First1, _Last1) to [_First2, _Last)
		char *_Pstate = (char *)&_State;
		_Mid1 = _First1;
		_Mid2 = _First2;

		for (; _Mid1 != _Last1 && _Mid2 != _Last2; )
			{	// convert a multibyte sequence
			unsigned char _By = (unsigned char)*_Mid1;
			unsigned long _Ch;
			int _Nextra;

			if (_By < 0x80)
				_Ch = _By, _Nextra = 0;
			else if (_By < 0xc0)
				{	// 0x80-0xdf not first byte
				++_Mid1;
				return (_Mybase::error);
				}
			else if (_By < 0xe0)
				_Ch = _By & 0x1f, _Nextra = 1;
			else if (_By < 0xf0)
				_Ch = _By & 0x0f, _Nextra = 2;
			else if (_By < 0xf8)
				_Ch = _By & 0x07, _Nextra = 3;
			else
				_Ch = _By & 0x03, _Nextra = _By < 0xfc ? 4 : 5;

			if (_Nextra == 0)
				++_Mid1;
			else if (_Last1 - _Mid1 < _Nextra + 1)
				break;	// not enough input
			else
				for (++_Mid1; 0 < _Nextra; --_Nextra, ++_Mid1)
					if ((_By = (unsigned char)*_Mid1) < 0x80 || 0xc0 <= _By)
						return (_Mybase::error);	// not continuation byte
					else
						_Ch = _Ch << 6 | (_By & 0x3f);

			if (*_Pstate == 0)
				{	// first time, maybe look for and consume header
				*_Pstate = 1;

				if ((_Mode & _Consume_header) != 0 && _Ch == 0xfeff)
					{	// drop header and retry
					result _Ans = do_in(_State, _Mid1, _Last1, _Mid1,
						_First2, _Last2, _Mid2);

					if (_Ans == _Mybase::partial)
						{	// roll back header determination
						*_Pstate = 0;
						_Mid1 = _First1;
						}
					return (_Ans);
					}
				}

			if (_Maxcode < _Ch)
				return (_Mybase::error);	// code too large
			*_Mid2++ = (_Elem)_Ch;
			}

		return (_First1 == _Mid1 ? _Mybase::partial : _Mybase::ok);
		}

	virtual result _CTHIS do_out(_Statype& _State,
		const _Elem *_First1, const _Elem *_Last1, const _Elem *& _Mid1,
		_Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
		{	// convert [_First1, _Last1) to bytes [_First2, _Last)
		char *_Pstate = (char *)&_State;
		_Mid1 = _First1;
		_Mid2 = _First2;

		for (; _Mid1 != _Last1 && _Mid2 != _Last2; )
			{	// convert and put a wide char
			_Byte _By;
			int _Nextra;
			unsigned long _Ch = (unsigned long)*_Mid1;

			if (_Maxcode < _Ch)
				return (_Mybase::error);

			if (_Ch < 0x0080)
				_By = (_Byte)_Ch, _Nextra = 0;
			else if (_Ch < 0x0800)
				_By = (_Byte)(0xc0 | _Ch >> 6), _Nextra = 1;
			else if (_Ch < 0x00010000)
				_By = (_Byte)(0xe0 | _Ch >> 12), _Nextra = 2;
			else if (_Ch < 0x00200000)
				_By = (_Byte)(0xf0 | _Ch >> 18), _Nextra = 3;
			else if (_Ch < 0x04000000)
				_By = (_Byte)(0xf8 | _Ch >> 24), _Nextra = 4;
			else
				_By = (_Byte)(0xfc | (_Ch >> 30 & 0x03)), _Nextra = 5;

			if (*_Pstate == 0)
				{	// first time, maybe generate header
				*_Pstate = 1;
				if ((_Mode & _Generate_header) == 0)
					;
				else if (_Last2 - _Mid2 < 3 + 1 + _Nextra)
					return (_Mybase::partial);	// not enough room for both
				else
					{	// prepend header
					*_Mid2++ = (_Byte)(unsigned char)0xef;
					*_Mid2++ = (_Byte)(unsigned char)0xbb;
					*_Mid2++ = (_Byte)(unsigned char)0xbf;
					}
				}

			if (_Last2 - _Mid2 < 1 + _Nextra)
				break;	// not enough room for output

			++_Mid1;
			for (*_Mid2++ = _By; 0 < _Nextra; )
				*_Mid2++ = (_Byte)((_Ch >> 6 * --_Nextra & 0x3f) | 0x80);
			}
		return (_First1 == _Mid1 ? _Mybase::partial : _Mybase::ok);
		}

	virtual result _CTHIS do_unshift(_Statype&,
		_Byte *_First2, _Byte *, _Byte *& _Mid2) const
		{	// generate bytes to return to default shift state
		_Mid2 = _First2;
		return (_Mybase::ok);
		}

	virtual int _CTHIS do_length(_Statype& _State, const _Byte *_First1,
		const _Byte *_Last1, size_t _Count) const
		{	// return min(_Count, converted length of bytes [_First1, _Last1))
		int _Wchars = 0;
		_Statype _Mystate = _State;

		for (; (size_t)_Wchars < _Count && _First1 != _Last1; )
			{	// convert another wide character
			const _Byte *_Mid1;
			_Elem *_Mid2;
			_Elem _Ch;

			switch (do_in(_Mystate, _First1, _Last1, _Mid1,
				&_Ch, &_Ch + 1, _Mid2))
				{	// test result of single wide-char conversion
			case _Mybase::noconv:
				return ((int)(_Wchars + (int)(_Last1 - _First1)));

			case _Mybase::ok:
				if (_Mid2 == &_Ch + 1)
					++_Wchars;	// replacement do_in might not convert one
				_First1 = _Mid1;
				break;

			default:
				return ((int)_Wchars);	// error or partial
				}
			}

		return ((int)_Wchars);
		}

	virtual bool _CTHIS do_always_noconv() const _THROW0()
		{	// return true if conversions never change input
		return (false);
		}

	virtual int _CTHIS do_max_length() const _THROW0()
		{	// return maximum length required for a conversion
		return ((_Mode & (_Consume_header | _Generate_header)) != 0
			? 9 : 6);
		}

	virtual int _CTHIS do_encoding() const _THROW0()
		{	// return length of code sequence (from codecvt)
		return ((_Mode & (_Consume_header | _Generate_header)) != 0
			? -1 : 0);	// -1 => state dependent, 0 => varying length
		}

private:
	unsigned long _Maxcode;	// default: 0xffffffff
	_Codecvt_mode _Mode;	// default: _Consume_header
	};
 #endif /* _HAS_CHAR16_T_LANGUAGE_SUPPORT */

		// CLASS codecvt<wchar_t, char, _Mbstatet>
template<>
	class _CRTIMP2P codecvt<wchar_t, char, _Mbstatet>
	: public codecvt_base
	{	// facet for converting between wchar_t and char (_Byte) sequences
public:
	typedef wchar_t _Elem;
	typedef char _Byte;
	typedef _Mbstatet _Statype;
	typedef _Elem intern_type;
	typedef _Byte extern_type;
	typedef _Statype state_type;

	result _CTHIS in(_Statype& _State,
		const _Byte *_First1, const _Byte *_Last1, const _Byte *& _Mid1,
		_Elem *_First2, _Elem *_Last2, _Elem *& _Mid2) const
		{	// convert bytes [_First1, _Last1) to [_First2, _Last)
		return (do_in(_State,
			_First1, _Last1, _Mid1, _First2, _Last2, _Mid2));
		}

	result _CTHIS out(_Statype& _State,
		const _Elem *_First1, const _Elem *_Last1, const _Elem *& _Mid1,
		_Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
		{	// convert [_First1, _Last1) to bytes [_First2, _Last)
		return (do_out(_State,
			_First1, _Last1, _Mid1, _First2, _Last2, _Mid2));
		}

	result _CTHIS unshift(_Statype& _State,
		_Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
		{	// generate bytes to return to default shift state
		return (do_unshift(_State,
			_First2, _Last2, _Mid2));
		}

	int _CTHIS length(_Statype& _State, const _Byte *_First1,
		const _Byte *_Last1, size_t _Count) const
		{	// return min(_Count, converted length of bytes [_First1, _Last1))
		return (do_length(_State, _First1, _Last1, _Count));
		}

	__PURE_APPDOMAIN_GLOBAL static locale::id id;

	explicit _CTHIS codecvt(size_t _Refs = 0)
		: codecvt_base(_Refs)
		{	// construct from current locale
		_BEGIN_LOCINFO(_Lobj)
			_Init(_Lobj);
		_END_LOCINFO()
		}

	_CTHIS codecvt(const _Locinfo& _Lobj, size_t _Refs = 0)
		: codecvt_base(_Refs)
		{	// construct from specified locale
		_Init(_Lobj);
		}

	static size_t _CCDECL _Getcat(const locale::facet **_Ppf = 0,
		const locale *_Ploc = 0)
		{	// return locale category mask and construct standard facet
		if (_Ppf != 0 && *_Ppf == 0)
			*_Ppf = new codecvt<_Elem, _Byte, _Statype>(
				_Locinfo(_Ploc->c_str()));
		return (_X_CTYPE);
		}

protected:
	virtual _CTHIS ~codecvt() _NOEXCEPT
		{	// destroy the object
		}

	void _CTHIS _Init(const _Locinfo& _Lobj)
		{	// initialize from _Lobj
		_Cvt = _Lobj._Getcvt();
		}

	virtual result _CTHIS do_in(_Statype& _State,
		const _Byte *_First1, const _Byte *_Last1, const _Byte *& _Mid1,
			_Elem *_First2, _Elem *_Last2, _Elem *& _Mid2) const
		{	// convert bytes [_First1, _Last1) to [_First2, _Last)
		_DEBUG_RANGE(_First1, _Last1);
		_DEBUG_RANGE(_First2, _Last2);
		_Mid1 = _First1, _Mid2 = _First2;
		result _Ans = _Mid1 == _Last1 ? ok : partial;
		int _Bytes;

		while (_Mid1 != _Last1 && _Mid2 != _Last2)
			switch (_Bytes = _Mbrtowc(_Mid2, _Mid1, _Last1 - _Mid1,
				&_State, &_Cvt))
			{	// test result of locale-specific mbrtowc call
			case -2:	// partial conversion
				_Mid1 = _Last1;
				return (_Ans);

			case -1:	// failed conversion
				return (error);

			case 0:	// may have converted null character
				if (*_Mid2 == (_Elem)0)
					_Bytes = (int)_CSTD strlen(_Mid1) + 1;
				// fall through

			default:	// converted _Bytes bytes to a wchar_t
				if (_Bytes == -3)
					_Bytes = 0;	// wchar_t generated from state info
				_Mid1 += _Bytes;
				++_Mid2;
				_Ans = ok;
			}
		return (_Ans);
		}

	virtual result _CTHIS do_out(_Statype& _State,
		const _Elem *_First1, const _Elem *_Last1, const _Elem *& _Mid1,
			_Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
		{	// convert [_First1, _Last1) to bytes [_First2, _Last)
		_DEBUG_RANGE(_First1, _Last1);
		_DEBUG_RANGE(_First2, _Last2);
		_Mid1 = _First1, _Mid2 = _First2;
		int _Bytes;

		while (_Mid1 != _Last1 && _Mid2 != _Last2)
			if ((int)MB_LEN_MAX <= _Last2 - _Mid2)
				if ((_Bytes = _Wcrtomb(_Mid2, *_Mid1,
					&_State, &_Cvt)) < 0)
					return (error);	// locale-specific wcrtomb failed
				else
					++_Mid1, _Mid2 += _Bytes;
			else
				{	// destination too small, convert into buffer
				_Byte _Buf[MB_LEN_MAX];
				_Statype _Stsave = _State;

				if ((_Bytes = _Wcrtomb(_Buf, *_Mid1,
					&_State, &_Cvt)) < 0)
					return (error);	// locale-specific wcrtomb failed
				else if (_Last2 - _Mid2 < _Bytes)
					{	// converted too many, roll back and return previous
					_State = _Stsave;
					break;
					}
				else
					{	// copy converted bytes from buffer
					_CSTD memcpy(_Mid2, _Buf, _Bytes);
					++_Mid1, _Mid2 += _Bytes;
					}
				}
		return (_Mid1 == _Last1 ? ok : partial);
		}

	virtual result _CTHIS do_unshift(_Statype& _State,
		_Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const
		{	// generate bytes to return to default shift state
		_DEBUG_RANGE(_First2, _Last2);
		_Mid2 = _First2;
		result _Ans = ok;
		int _Bytes;
		_Byte _Buf[MB_LEN_MAX];
		_Statype _Stsave = _State;

		if ((_Bytes = _Wcrtomb(_Buf, L'\0', &_State, &_Cvt)) <= 0)
			_Ans = error;	// locale-specific wcrtomb failed
		else if (_Last2 - _Mid2 < --_Bytes)
			{	// converted too many, roll back and return
			_State = _Stsave;
			_Ans = partial;
			}
		else if (0 < _Bytes)
			{	// copy converted bytes from buffer
			_CSTD memcpy(_Mid2, _Buf, _Bytes);
			_Mid2 += _Bytes;
			}
		return (_Ans);
		}

	virtual int _CTHIS do_length(_Statype& _State, const _Byte *_First1,
		const _Byte *_Last1, size_t _Count) const
		{	// return min(_Count, converted length of bytes [_First1, _Last1))
		_DEBUG_RANGE(_First1, _Last1);
		int _Wchars;
		const _Byte *_Mid1;
		_Statype _Mystate = _State;

		for (_Wchars = 0, _Mid1 = _First1;
			(size_t)_Wchars < _Count && _Mid1 != _Last1; )
			{	// convert another wchar_t
			int _Bytes;
			_Elem _Ch;

			switch (_Bytes = _Mbrtowc(&_Ch, _Mid1, _Last1 - _Mid1,
				&_Mystate, &_Cvt))
				{	// test result of locale-specific mbrtowc call
			case -2:	// partial conversion
				return (_Wchars);

			case -1:	// failed conversion
				return (_Wchars);

			case 0:	// may have converted null character
				if (_Ch == (_Elem)0)
					_Bytes = (int)_CSTD strlen(_Mid1) + 1;
				// fall through

			default:	// converted _Bytes bytes to a wchar_t
				if (_Bytes == -3)
					_Bytes = 0;	// wchar_t generated from state info
				_Mid1 += _Bytes;
				++_Wchars;
				}
			}
		return (_Wchars);
		}

	virtual bool _CTHIS do_always_noconv() const _THROW0()
		{	// return true if conversions never change input
		return (false);
		}

	virtual int _CTHIS do_max_length() const _THROW0()
		{	// return maximum length required for a conversion (from codecvt)
		return (MB_LEN_MAX);
		}

	virtual int _CTHIS do_encoding() const _THROW0()
		{	// return length of code sequence (from codecvt)
		return (0);	// 0 => varying length
		}

private:
	_Locinfo::_Cvtvec _Cvt;	// locale info passed to _Mbrtowc, _Wcrtomb
	};

		// TEMPLATE CLASS codecvt_byname
template<class _Elem,
	class _Byte,
	class _Statype>
	class codecvt_byname
		: public codecvt<_Elem, _Byte, _Statype>
	{	// codecvt for named locale
public:
	explicit _CTHIS codecvt_byname(const char *_Locname, size_t _Refs = 0)
		: codecvt<_Elem, _Byte, _Statype>(_Locinfo(_Locname), _Refs)
		{	// construct for named locale
		}

 #if _HAS_CPP0X
	explicit _CTHIS codecvt_byname(const string& _Str, size_t _Refs = 0)
		: codecvt<_Elem, _Byte, _Statype>(_Locinfo(_Str.c_str()), _Refs)
		{	// construct for named locale
		}
 #endif /* _HAS_CPP0X */

protected:
	virtual _CTHIS ~codecvt_byname() _NOEXCEPT
		{	// destroy the object
		}
	};

		// STRUCT ctype_base

struct _CRTIMP2P ctype_base
	: public locale::facet
	{	// base for ctype
	enum
		{	// constants for character classifications
		alnum = _DI | _LO | _UP | _XA, alpha = _LO | _UP | _XA,
		cntrl = _BB, digit = _DI, graph = _DI | _LO | _PU | _UP | _XA,
		lower = _LO, print = _DI | _LO | _PU | _SP | _UP | _XA | _XD,
		punct = _PU, space = _CN | _SP | _XS, upper = _UP,
		xdigit = _XD, blank = _CN | _SP | _XS | _XB};
	typedef short mask;	// to match <ctype.h>

	_CTHIS ctype_base(size_t _Refs = 0)
		: locale::facet(_Refs)
		{	// default constructor
		}

	_CTHIS ~ctype_base() _NOEXCEPT
		{	// destroy the object
		}
	};

		// TEMPLATE CLASS ctype
template<class _Elem>
	class ctype
		: public ctype_base
	{	// facet for classifying elements, converting cases
public:
	typedef _Elem char_type;

	bool _CTHIS is(mask _Maskval, _Elem _Ch) const
		{	// test if element fits any mask classifications
		return (do_is(_Maskval, _Ch));
		}

	const _Elem *_CTHIS is(const _Elem *_First, const _Elem *_Last,
		mask *_Dest) const
		{	// get mask sequence for elements in [_First, _Last)
		return (do_is(_First, _Last, _Dest));
		}

	const _Elem *_CTHIS scan_is(mask _Maskval, const _Elem *_First,
		const _Elem *_Last) const
		{	// find first in [_First, _Last) that fits mask classification
		return (do_scan_is(_Maskval, _First, _Last));
		}

	const _Elem *_CTHIS scan_not(mask _Maskval, const _Elem *_First,
		const _Elem *_Last) const
		{	// find first in [_First, _Last) not fitting mask classification
		return (do_scan_not(_Maskval, _First, _Last));
		}

	_Elem _CTHIS tolower(_Elem _Ch) const
		{	// convert element to lower case
		return (do_tolower(_Ch));
		}

	const _Elem *_CTHIS tolower(_Elem *_First, const _Elem *_Last) const
		{	// convert [_First, _Last) in place to lower case
		return (do_tolower(_First, _Last));
		}

	_Elem _CTHIS toupper(_Elem _Ch) const
		{	// convert element to upper case
		return (do_toupper(_Ch));
		}

	const _Elem *_CTHIS toupper(_Elem *_First, const _Elem *_Last) const
		{	// convert [_First, _Last) in place to upper case
		return (do_toupper(_First, _Last));
		}

	_Elem _CTHIS widen(char _Byte) const
		{	// widen char
		return (do_widen(_Byte));
		}

	const char *_CTHIS widen(const char *_First, const char *_Last,
		_Elem *_Dest) const
		{	// widen chars in [_First, _Last)
		return (do_widen(_First, _Last, _Dest));
		}

	char _CTHIS narrow(_Elem _Ch, char _Dflt = '\0') const
		{	// narrow element to char
		return (do_narrow(_Ch, _Dflt));
		}

	const _Elem *_CTHIS narrow(const _Elem *_First, const _Elem *_Last,
		char _Dflt, char *_Dest) const
		{	// narrow elements in [_First, _Last) to chars
		return (do_narrow(_First, _Last, _Dflt, _Dest));
		}

	__PURE_APPDOMAIN_GLOBAL static locale::id id;

	explicit _CTHIS ctype(size_t _Refs = 0)
		: ctype_base(_Refs)
		{	// construct from current locale
		_BEGIN_LOCINFO(_Lobj)
			_Init(_Lobj);
		_END_LOCINFO()
		}

	_CTHIS ctype(const _Locinfo& _Lobj, size_t _Refs = 0)
		: ctype_base(_Refs)
		{	// construct from specified locale
		_Init(_Lobj);
		}

	static size_t _CCDECL _Getcat(const locale::facet **_Ppf = 0,
		const locale *_Ploc = 0)
		{	// return locale category mask and construct standard facet
		if (_Ppf != 0 && *_Ppf == 0)
			*_Ppf = new ctype<_Elem>(
				_Locinfo(_Ploc->c_str()));
		return (_X_CTYPE);
		}

protected:
	virtual _CTHIS ~ctype() _NOEXCEPT
		{	// destroy the object
		if (_Ctype._Delfl)
			_CSTD free((void *)_Ctype._Table);
		}

	void _CTHIS _Init(const _Locinfo& _Lobj)
		{	// initialize from _Lobj
		_Ctype = _Lobj._Getctype();
		_Cvt = _Lobj._Getcvt();
		}

	virtual bool _CTHIS do_is(mask _Maskval, _Elem _Ch) const
		{	// test if element fits any mask classifications
		return ((_Ctype._Table[(unsigned char)narrow(_Ch)]
			& _Maskval) != 0);
		}

	virtual const _Elem *_CTHIS do_is(const _Elem *_First, const _Elem *_Last,
		mask *_Dest) const
		{	// get mask sequence for elements in [_First, _Last)
		_DEBUG_RANGE_PTR(_First, _Last, _Dest);
		for (; _First != _Last; ++_First, ++_Dest)
			*_Dest = _Ctype._Table[(unsigned char)narrow(*_First)];
		return (_First);
		}

	virtual const _Elem *_CTHIS do_scan_is(mask _Maskval,
		const _Elem *_First, const _Elem *_Last) const
		{	// find first in [_First, _Last) that fits mask classification
		_DEBUG_RANGE(_First, _Last);
		for (; _First != _Last && !is(_Maskval, *_First); ++_First)
			;
		return (_First);
		}

	virtual const _Elem *_CTHIS do_scan_not(mask _Maskval,
		const _Elem *_First, const _Elem *_Last) const
		{	// find first in [_First, _Last) not fitting mask classification
		_DEBUG_RANGE(_First, _Last);
		for (; _First != _Last && is(_Maskval, *_First); ++_First)
			;
		return (_First);
		}

	virtual _Elem _CTHIS do_tolower(_Elem _Ch) const
		{	// convert element to lower case
		unsigned char _Byte = (unsigned char)narrow(_Ch, '\0');
		if (_Byte == '\0')
			return (_Ch);
		else
			return (widen((char)_Tolower(_Byte, &_Ctype)));
		}

	virtual const _Elem *_CTHIS do_tolower(_Elem *_First,
		const _Elem *_Last) const
		{	// convert [_First, _Last) in place to lower case
		_DEBUG_RANGE((const _Elem *)_First, _Last);
		for (; _First != _Last; ++_First)
			{	// convert *_First to lower case
			unsigned char _Byte = (unsigned char)narrow(*_First, '\0');
			if (_Byte != '\0')
				*_First = (widen((char)_Tolower(_Byte, &_Ctype)));
			}
		return ((const _Elem *)_First);
		}

	virtual _Elem _CTHIS do_toupper(_Elem _Ch) const
		{	// convert element to upper case
		unsigned char _Byte = (unsigned char)narrow(_Ch, '\0');
		if (_Byte == '\0')
			return (_Ch);
		else
			return (widen((char)_Toupper(_Byte, &_Ctype)));
		}

	virtual const _Elem *_CTHIS do_toupper(_Elem *_First,
		const _Elem *_Last) const
		{	// convert [_First, _Last) in place to upper case
		_DEBUG_RANGE((const _Elem *)_First, _Last);
		for (; _First != _Last; ++_First)
			{	// convert *_First to upper case
			unsigned char _Byte = (unsigned char)narrow(*_First, '\0');
			if (_Byte != '\0')
				*_First = (widen((char)_Toupper(_Byte, &_Ctype)));
			}
		return ((const _Elem *)_First);
		}

	virtual _Elem _CTHIS do_widen(char _Byte) const
		{	// widen char
		return (_MAKLOCCHR(_Elem, _Byte, _Cvt));
		}

	virtual const char *_CTHIS do_widen(const char *_First,
		const char *_Last, _Elem *_Dest) const
		{	// widen chars in [_First, _Last)
		_DEBUG_RANGE_PTR(_First, _Last, _Dest);
		for (; _First != _Last; ++_First, ++_Dest)
			*_Dest = _MAKLOCCHR(_Elem, *_First, _Cvt);
		return (_First);
		}

	char _CTHIS _Donarrow(_Elem _Ch, char _Dflt) const
		{	// narrow element to char
		char _Byte;
		if (_Ch == (_Elem)0)
			return ('\0');
		else if ((_Byte = _MAKLOCBYTE(_Elem, _Ch, _Cvt)) == '\0')
			return (_Dflt);
		else
			return (_Byte);
		}

	virtual char _CTHIS do_narrow(_Elem _Ch, char _Dflt) const
		{	// narrow element to char
		return (_Donarrow(_Ch, _Dflt));
		}

	virtual const _Elem *_CTHIS do_narrow(const _Elem *_First,
		const _Elem *_Last, char _Dflt, char *_Dest) const
		{	// narrow elements in [_First, _Last) to chars
		_DEBUG_RANGE_PTR(_First, _Last, _Dest);
		for (; _First != _Last; ++_First, ++_Dest)
			*_Dest = _Donarrow(*_First, _Dflt);
		return (_First);
		}

private:
	_Locinfo::_Ctypevec _Ctype;	// locale info passed to _Tolower, etc.
	_Locinfo::_Cvtvec _Cvt;		// conversion information
	};

		// STATIC ctype::id OBJECT
template<class _Elem>
	locale::id ctype<_Elem>::id;

		// CLASS ctype<char>
template<>
	class _CRTIMP2P ctype<char>
	: public ctype_base
	{	// facet for classifying char elements, converting cases
	typedef ctype<char> _Myt;

public:
	typedef char _Elem;
	typedef _Elem char_type;

	bool _CTHIS is(mask _Maskval, _Elem _Ch) const
		{	// test if element fits any mask classifications
		return ((_Ctype._Table[(unsigned char)_Ch] & _Maskval) != 0);
		}

	const _Elem *_CTHIS is(const _Elem *_First,
		const _Elem *_Last, mask *_Dest) const
		{	// get mask sequence for elements in [_First, _Last)
		_DEBUG_RANGE_PTR(_First, _Last, _Dest);
		for (; _First != _Last; ++_First, ++_Dest)
			*_Dest = _Ctype._Table[(unsigned char)*_First];
		return (_First);
		}

	const _Elem *_CTHIS scan_is(mask _Maskval,
		const _Elem *_First, const _Elem *_Last) const
		{	// find first in [_First, _Last) that fits mask classification
		_DEBUG_RANGE(_First, _Last);
		for (; _First != _Last && !is(_Maskval, *_First); ++_First)
			;
		return (_First);
		}

	const _Elem *_CTHIS scan_not(mask _Maskval,
		const _Elem *_First, const _Elem *_Last) const
		{	// find first in [_First, _Last) not fitting mask classification
		_DEBUG_RANGE(_First, _Last);
		for (; _First != _Last && is(_Maskval, *_First); ++_First)
			;
		return (_First);
		}

	_Elem _CTHIS tolower(_Elem _Ch) const
		{	// convert element to lower case
		return (do_tolower(_Ch));
		}

	const _Elem *_CTHIS tolower(_Elem *_First, const _Elem *_Last) const
		{	// convert [_First, _Last) in place to lower case
		return (do_tolower(_First, _Last));
		}

	_Elem _CTHIS toupper(_Elem _Ch) const
		{	// convert element to upper case
		return (do_toupper(_Ch));
		}

	const _Elem *_CTHIS toupper(_Elem *_First, const _Elem *_Last) const
		{	// convert [_First, _Last) in place to upper case
		return (do_toupper(_First, _Last));
		}

	_Elem _CTHIS widen(char _Byte) const
		{	// widen char
		return (do_widen(_Byte));
		}

	const _Elem *_CTHIS widen(const char *_First, const char *_Last,
		_Elem *_Dest) const
		{	// widen chars in [_First, _Last)
		return (do_widen(_First, _Last, _Dest));
		}

	_Elem _CTHIS narrow(_Elem _Ch, char _Dflt = '\0') const
		{	// narrow element to char
		return (do_narrow(_Ch, _Dflt));
		}

	const _Elem *_CTHIS narrow(const _Elem *_First, const _Elem *_Last,
		char _Dflt, char *_Dest) const
		{	// narrow elements in [_First, _Last) to chars
		return (do_narrow(_First, _Last, _Dflt, _Dest));
		}

	__PURE_APPDOMAIN_GLOBAL static locale::id id;

	explicit _CTHIS ctype(const mask *_Table = 0,
		bool _Deletetable = false,
		size_t _Refs = 0)
		: ctype_base(_Refs)
		{	// construct with specified table and delete flag for table
		_BEGIN_LOCINFO(_Lobj)
			_Init(_Lobj);
		_END_LOCINFO()

		_Tidy();	// free existing table, as needed
		if (_Table != 0)
			{	// replace existing char to mask table
			_Ctype._Table = _Table;
			_Ctype._Delfl = _Deletetable ? -1 : 0;
			}
		else
			{	// use classic table
			_Ctype._Table = classic_table();
			_Ctype._Delfl = 0;
			}
		}

	_CTHIS ctype(const _Locinfo& _Lobj, size_t _Refs = 0)
		: ctype_base(_Refs)
		{	// construct from current locale
		_Init(_Lobj);
		}

	static size_t _CCDECL _Getcat(const locale::facet **_Ppf = 0,
		const locale *_Ploc = 0)
		{	// return locale category mask and construct standard facet
		if (_Ppf != 0 && *_Ppf == 0)
			*_Ppf = new ctype<_Elem>(
				_Locinfo(_Ploc->c_str()));
		return (_X_CTYPE);
		}

	const mask *_CTHIS table() const _THROW0()
		{	// return address of char to mask table
		return (_Ctype._Table);
		}

	static const mask *_CCDECL classic_table() _THROW0()
		{	// return address of char to mask table for "C" locale
		const _Myt& _Ctype_fac = use_facet< _Myt >(locale::classic());
		return (_Ctype_fac.table());
		}

	_PGLOBAL static const size_t table_size;	// size of _Ctype._Table

protected:
	virtual _CTHIS ~ctype() _NOEXCEPT
		{	// destroy the object
		_Tidy();
		}

	void _CTHIS _Init(const _Locinfo& _Lobj)
		{	// initialize from _Lobj
 #if __BORLANDC__	/* compiler test */
		*(size_t *)&table_size = 1 << CHAR_BIT;	// force space reservation
 #endif /* __BORLANDC__ */

		_Ctype = _Lobj._Getctype();
		}

	void _CTHIS _Tidy()
		{	// free any allocated storage
		if (0 < _Ctype._Delfl)
			_CSTD free((void *)_Ctype._Table);
		else if (_Ctype._Delfl < 0)
			delete[] _Ctype._Table;
		}

	virtual _Elem _CTHIS do_tolower(_Elem _Ch) const
		{	// convert element to lower case
		return ((_Elem)_Tolower((unsigned char)_Ch, &_Ctype));
		}

	virtual const _Elem *_CTHIS do_tolower(_Elem *_First,
		const _Elem *_Last) const
		{	// convert [_First, _Last) in place to lower case
		_DEBUG_RANGE((const _Elem *)_First, _Last);
		for (; _First != _Last; ++_First)
			*_First = (_Elem)_Tolower((unsigned char)*_First, &_Ctype);
		return ((const _Elem *)_First);
		}

	virtual _Elem _CTHIS do_toupper(_Elem _Ch) const
		{	// convert element to upper case
		return ((_Elem)_Toupper((unsigned char)_Ch, &_Ctype));
		}

	virtual const _Elem *_CTHIS do_toupper(_Elem *_First,
		const _Elem *_Last) const
		{	// convert [_First, _Last) in place to upper case
		_DEBUG_RANGE((const _Elem *)_First, _Last);
		for (; _First != _Last; ++_First)
			*_First = (_Elem)_Toupper((unsigned char)*_First, &_Ctype);
		return ((const _Elem *)_First);
		}

	virtual _Elem _CTHIS do_widen(char _Byte) const
		{	// widen char
		return (_Byte);
		}

	virtual const _Elem *_CTHIS do_widen(const char *_First,
		const char *_Last, _Elem *_Dest) const
		{	// widen chars in [_First, _Last)
		_DEBUG_RANGE_PTR(_First, _Last, _Dest);
		_CSTD memcpy(_Dest, _First, _Last - _First);
		return (_Last);
		}

	virtual _Elem _CTHIS do_narrow(_Elem _Ch, char) const
		{	// narrow char
		return (_Ch);
		}

	virtual const _Elem *_CTHIS do_narrow(const _Elem *_First,
		const _Elem *_Last, char, char *_Dest) const
		{	// narrow elements in [_First, _Last) to chars
		_DEBUG_RANGE_PTR(_First, _Last, _Dest);
		_CSTD memcpy(_Dest, _First, _Last - _First);
		return (_Last);
		}

private:
	_Locinfo::_Ctypevec _Ctype;	// information
	};

		// CLASS ctype<wchar_t>
template<>
	class _CRTIMP2P ctype<wchar_t>
	: public ctype_base
	{	// facet for classifying wchar_t elements, converting cases
	typedef ctype<wchar_t> _Myt;

public:
	typedef wchar_t _Elem;
	typedef _Elem char_type;

	bool _CTHIS is(mask _Maskval, _Elem _Ch) const
		{	// test if element fits any mask classifications
		return (do_is(_Maskval, _Ch));
		}

	const _Elem *_CTHIS is(const _Elem *_First, const _Elem *_Last,
		mask *_Dest) const
		{	// get mask sequence for elements in [_First, _Last)
		return (do_is(_First, _Last, _Dest));
		}

	const _Elem *_CTHIS scan_is(mask _Maskval, const _Elem *_First,
		const _Elem *_Last) const
		{	// find first in [_First, _Last) that fits mask classification
		return (do_scan_is(_Maskval, _First, _Last));
		}

	const _Elem *_CTHIS scan_not(mask _Maskval, const _Elem *_First,
		const _Elem *_Last) const
		{	// find first in [_First, _Last) not fitting mask classification
		return (do_scan_not(_Maskval, _First, _Last));
		}

	_Elem _CTHIS tolower(_Elem _Ch) const
		{	// convert element to lower case
		return (do_tolower(_Ch));
		}

	const _Elem *_CTHIS tolower(_Elem *_First, const _Elem *_Last) const
		{	// convert [_First, _Last) in place to lower case
		return (do_tolower(_First, _Last));
		}

	_Elem _CTHIS toupper(_Elem _Ch) const
		{	// convert element to upper case
		return (do_toupper(_Ch));
		}

	const _Elem *_CTHIS toupper(_Elem *_First, const _Elem *_Last) const
		{	// convert [_First, _Last) in place to upper case
		return (do_toupper(_First, _Last));
		}

	_Elem _CTHIS widen(char _Byte) const
		{	// widen char
		return (do_widen(_Byte));
		}

	const char *_CTHIS widen(const char *_First, const char *_Last,
		_Elem *_Dest) const
		{	// widen chars in [_First, _Last)
		return (do_widen(_First, _Last, _Dest));
		}

	char _CTHIS narrow(_Elem _Ch, char _Dflt = '\0') const
		{	// narrow element to char
		return (do_narrow(_Ch, _Dflt));
		}

	const _Elem *_CTHIS narrow(const _Elem *_First, const _Elem *_Last,
		char _Dflt, char *_Dest) const
		{	// narrow elements in [_First, _Last) to chars
		return (do_narrow(_First, _Last, _Dflt, _Dest));
		}

	__PURE_APPDOMAIN_GLOBAL static locale::id id;

	explicit _CTHIS ctype(size_t _Refs = 0)
		: ctype_base(_Refs)
		{	// construct from current locale
		_BEGIN_LOCINFO(_Lobj)
			_Init(_Lobj);
		_END_LOCINFO()
		}

	_CTHIS ctype(const _Locinfo& _Lobj, size_t _Refs = 0)
		: ctype_base(_Refs)
		{	// construct from specified locale
		_Init(_Lobj);
		}

	static size_t _CCDECL _Getcat(const locale::facet **_Ppf = 0,
		const locale *_Ploc = 0)
		{	// return locale category mask and construct standard facet
		if (_Ppf != 0 && *_Ppf == 0)
			*_Ppf = new ctype<_Elem>(
				_Locinfo(_Ploc->c_str()));
		return (_X_CTYPE);
		}

protected:
	virtual _CTHIS ~ctype() _NOEXCEPT
		{	// destroy the object
		if (_Ctype._Delfl)
			_CSTD free((void *)_Ctype._Table);
		}

	void _CTHIS _Init(const _Locinfo& _Lobj)
		{	// initialize from _Lobj
		_Ctype = _Lobj._Getctype();
		_Cvt = _Lobj._Getcvt();
		}

	virtual bool _CTHIS do_is(mask _Maskval, _Elem _Ch) const
		{	// test if element fits any mask classifications
		return ((_Ctype._Table[(unsigned char)narrow(_Ch)]
			& _Maskval) != 0);
		}

	virtual const _Elem *_CTHIS do_is(const _Elem *_First,
		const _Elem *_Last, mask *_Dest) const
		{	// get mask sequence for elements in [_First, _Last)
		_DEBUG_RANGE_PTR(_First, _Last, _Dest);
		for (; _First != _Last; ++_First, ++_Dest)
			*_Dest = _Ctype._Table[(unsigned char)narrow(*_First)];
		return (_First);
		}

	virtual const _Elem *_CTHIS do_scan_is(mask _Maskval,
		const _Elem *_First, const _Elem *_Last) const
		{	// find first in [_First, _Last) that fits mask classification
		_DEBUG_RANGE(_First, _Last);
		for (; _First != _Last && !is(_Maskval, *_First); ++_First)
			;
		return (_First);
		}

	virtual const _Elem *_CTHIS do_scan_not(mask _Maskval,
		const _Elem *_First, const _Elem *_Last) const
		{	// find first in [_First, _Last) not fitting mask classification
		_DEBUG_RANGE(_First, _Last);
		for (; _First != _Last && is(_Maskval, *_First); ++_First)
			;
		return (_First);
		}

	virtual _Elem _CTHIS do_tolower(_Elem _Ch) const
		{	// convert element to lower case
		unsigned char _Byte = (unsigned char)narrow(_Ch, '\0');
		if (_Byte == '\0')
			return (_Ch);
		else
			return (widen((char)_Tolower(_Byte, &_Ctype)));
		}

	virtual const _Elem *_CTHIS do_tolower(_Elem *_First,
		const _Elem *_Last) const
		{	// convert [_First, _Last) in place to lower case
		_DEBUG_RANGE((const _Elem *)_First, _Last);
		for (; _First != _Last; ++_First)
			{	// convert *_First to lower case
			unsigned char _Byte = (unsigned char)narrow(*_First, '\0');
			if (_Byte != '\0')
				*_First = (widen((char)_Tolower(_Byte, &_Ctype)));
			}
		return ((const _Elem *)_First);
		}

	virtual _Elem _CTHIS do_toupper(_Elem _Ch) const
		{	// convert element to upper case
		unsigned char _Byte = (unsigned char)narrow(_Ch, '\0');
		if (_Byte == '\0')
			return (_Ch);
		else
			return (widen((char)_Toupper(_Byte, &_Ctype)));
		}

	virtual const _Elem *_CTHIS do_toupper(_Elem *_First,
		const _Elem *_Last) const
		{	// convert [_First, _Last) in place to upper case
		_DEBUG_RANGE((const _Elem *)_First, _Last);
		for (; _First != _Last; ++_First)
			{	// convert *_First to upper case
			unsigned char _Byte = (unsigned char)narrow(*_First, '\0');
			if (_Byte != '\0')
				*_First = (widen((char)_Toupper(_Byte, &_Ctype)));
			}
		return ((const _Elem *)_First);
		}

	_Elem _CTHIS _Dowiden(char _Byte) const
		{	// widen char
		_Mbstinit(_Mbst);
		wchar_t _Wc;
		return (_Mbrtowc(&_Wc, &_Byte, 1, &_Mbst, &_Cvt) < 0
			? (wchar_t)WEOF : _Wc);
		}

	virtual _Elem _CTHIS do_widen(char _Byte) const
		{	// widen char
		return (_Dowiden(_Byte));
		}

	virtual const char *_CTHIS do_widen(const char *_First,
		const char *_Last, _Elem *_Dest) const
		{	// widen chars in [_First, _Last)
		_DEBUG_RANGE_PTR(_First, _Last, _Dest);
		for (; _First != _Last; ++_First, ++_Dest)
			*_Dest = _Dowiden(*_First);
		return (_First);
		}

	char _CTHIS _Donarrow(_Elem _Ch, char _Dflt) const
		{	// narrow element to char
		char _Buf[MB_LEN_MAX];
		_Mbstinit(_Mbst);
		return (_Wcrtomb(_Buf, _Ch, &_Mbst, &_Cvt) != 1
			? _Dflt : _Buf[0]);
		}

	virtual char _CTHIS do_narrow(_Elem _Ch, char _Dflt) const
		{	// narrow element to char
		return (_Donarrow(_Ch, _Dflt));
		}

	virtual const _Elem *_CTHIS do_narrow(const _Elem *_First,
		const _Elem *_Last, char _Dflt, char *_Dest) const
		{	// narrow elements in [_First, _Last) to chars
		_DEBUG_RANGE_PTR(_First, _Last, _Dest);
		for (; _First != _Last; ++_First, ++_Dest)
			*_Dest = _Donarrow(*_First, _Dflt);
		return (_First);
		}

private:
	_Locinfo::_Ctypevec _Ctype;	// locale info passed to _Tolower, etc.
	_Locinfo::_Cvtvec _Cvt;		// conversion information
	};

		// TEMPLATE CLASS ctype_byname
template<class _Elem>
	class ctype_byname
	: public ctype<_Elem>
	{	// ctype for named locale
public:
	explicit _CTHIS ctype_byname(const char *_Locname, size_t _Refs = 0)
		: ctype<_Elem>(_Locinfo(_Locname), _Refs)
		{	// construct for named locale
		}

 #if _HAS_CPP0X
	explicit _CTHIS ctype_byname(const string& _Str, size_t _Refs = 0)
		: ctype<_Elem>(_Locinfo(_Str.c_str()), _Refs)
		{	// construct for named locale
		}
 #endif /* _HAS_CPP0X */

protected:
	virtual _CTHIS ~ctype_byname() _NOEXCEPT
		{	// destroy the object
		}
	};

		// TEMPLATE CLASS ctype_byname<char>
template<>
	class ctype_byname<char>
	: public ctype<char>
	{	// ctype_byname<char> for named locale
public:
	explicit _CTHIS ctype_byname(const char *_Locname, size_t _Refs = 0)
		: ctype<char>(_Locinfo(_Locname), _Refs)
		{	// construct for named locale
		}

 #if _HAS_CPP0X
	explicit _CTHIS ctype_byname(const string& _Str, size_t _Refs = 0)
		: ctype<char>(_Locinfo(_Str.c_str()), _Refs)
		{	// construct for named locale
		}
 #endif /* _HAS_CPP0X */

protected:
	virtual _CTHIS ~ctype_byname() _NOEXCEPT
		{	// destroy the object
		}
	};

#if defined(__CODEGEARC__)
 #ifdef  _DLL

  #ifdef __FORCE_INSTANCE
template class _CRTIMP2 codecvt<char, char, _Mbstatet>;

//template class _CRTIMP2 codecvt<wchar_t, char, _Mbstatet>;

   #ifdef _CRTBLD_NATIVE_WCHAR_T
template class _CRTIMP2 codecvt<unsigned short, char, _Mbstatet>;
   #endif /* _CRTBLD_NATIVE_WCHAR_T */

  #else /* __FORCE_INSTANCE */
_CRTEXT  template class _CRTIMP2 codecvt<char, char, _Mbstatet>;

//_CRTEXT  template class _CRTIMP2 codecvt<wchar_t, char, _Mbstatet>;

   #ifdef _CRTBLD_NATIVE_WCHAR_T
_CRTEXT  template class _CRTIMP2 codecvt<unsigned short, char, _Mbstatet>;
   #endif /* _CRTBLD_NATIVE_WCHAR_T */

  #endif /* __FORCE_INSTANCE */
 #endif /* _DLL */
#endif /* __CODEGEARC__ */

_STD_END
#endif /* _XLOCALE_ */

/*
 * Copyright (c) by P.J. Plauger. All rights reserved.
 * Consult your license regarding permissions and restrictions.
V6.50:1422 */
